#pragma once

#include "glare.d3d11.Prerequisites.h"
#include "glare.core.DrawContext.h"

namespace Glare {

	class D3D11DrawContext : public DrawContext
	{
	//public : const static int MAX_MRT_COUNT;

	public : D3D11DrawContext(D3D11Driver* driver, ID3D11DeviceContext* d3d_device_context);
	public : ~D3D11DrawContext();

	public : virtual void ClearRenderTarget(RenderTarget* render_target, const ColourValue& clear_color);
	public : virtual void Draw(const uint& vertex_count, const uint& start_vertex = 0);
	public : virtual void DrawIndexed(const uint& index_count, const uint& start_index, const uint& vertex_offset);
	public : virtual void UpdateGpuResource(GpuResource* destination_resource, const uint& dest_sub_resource, Box* dest_box, const void* src_data, const uint& src_row_pitch, const uint& src_depth_pitch);

	public : virtual void IA_SetIndexBuffer(GpuBuffer* buffer, const bool& format_32bit, const uint& offset);
	public : virtual void IA_SetVertexBuffer(const GpuVertexBufferBinding& vertex_buffer_binding, const uint& start_slot = 0);
	public : virtual void IA_SetVertexBuffers(const GpuVertexBufferBinding bindings[], const uint& num_bindings, const uint& start_slot = 0);
	public : virtual void IA_SetPrimitiveType(const GpuPrimitive::Type& primitive_type);
	public : virtual void IA_SetInputDeclaration(ShaderInputDeclaration* declaration);

	public : virtual void VT_SetWorldMatrix(const Matrix4 &m);
	public : virtual void VT_SetViewMatrix(const Matrix4 &m);
	public : virtual void VT_SetProjectionMatrix(const Matrix4 &m);

	public : virtual void VS_SetVertexShader(VertexShader* shader);
	public : virtual void VS_SetConstantBuffer(const uint& slot, GpuBuffer* constant_buffer);

	public : virtual void RS_SetViewport(const Viewport& viewport);
	public : virtual void RS_SetViewports(uint num_viewports, const Viewport* viewport_array);

	public : virtual void PS_SetPixelShader(PixelShader* shader);
	public : virtual void PS_SetSamplerState(const uint& slot, SamplerState* sampler_state);
	public : virtual void PS_SetShaderResource(const uint& slot, ShaderResourceView* resource_view);

	public : virtual void OM_SetRenderTarget(RenderTarget* render_target, DepthBuffer* depth_buffer);
	public : virtual void OM_SetMultiRenderTargets(RenderTarget** render_targets, int num_targets, DepthBuffer* depth_buffer);

	public : virtual Driver* GetDriver() const;

	public : ID3D11DeviceContext* GetD3DDeviceContext() const;

	private : D3D11Driver* _driver;
	private : ID3D11DeviceContext* _d3d_device_context;
	private : ID3D11RenderTargetView* _d3d_rt_view_array[16];
	private : ID3D11Buffer* _d3d_vertex_buffer_array[16];
	private : uint _d3d_vertex_buffer_strides[16];
	private : uint _d3d_vertex_buffer_offsets[16];
	};
}